package com.sense.kukoo.biz_media.vm

import android.util.Log
import androidx.lifecycle.MutableLiveData
import com.sense.kukoo.common.mvvm.model.BaseMvvmModel
import com.sense.kukoo.common.mvvm.vm.BaseViewModel
import com.sense.kukoo.common.repo.Repo
import com.sense.kukoo.common.repo.biz.CommentContentBean
import com.sense.kukoo.common.repo.http.bean.CommentRecordBean

class MediaCommentViewModel: BaseViewModel() {

    private val TAG: String = javaClass.simpleName

    private lateinit var comments: ArrayList<CommentRecordBean>

    private var mPageIndex = 2
    private val mPageSize = 10
    private val mSubCommentPageSize = 10
    private var contentId: Long = -1
    private var creatorId: Long = -1
    private var errorRetry: ()->Unit = {}

    val action_finishRefresh: MutableLiveData<Boolean> = MutableLiveData()
    val action_finishLoadMore: MutableLiveData<Boolean> = MutableLiveData()
    val action_networkError: MutableLiveData<Boolean> = MutableLiveData()
    val data_commentList: MutableLiveData<ArrayList<CommentContentBean>> = MutableLiveData()
    val data_enableLoadMore:MutableLiveData<Boolean> = MutableLiveData()

    override fun createModel(): BaseMvvmModel? = null

    fun setData(contentId: Long, creatorId: Long){
        this.contentId = contentId
        this.creatorId = creatorId
    }

    override fun initData() {}

    fun onErrorRetry(){
        errorRetry()
    }

    private fun showComments(){
        if (comments.isEmpty()) {
            val list = arrayListOf<CommentContentBean>()
            list.add(CommentContentBean(CommentContentBean.TYPE_NO_COMMENT, null))
            list.add(CommentContentBean(CommentContentBean.TYPE_SPACE_FOR_LISTEN_NOW, null))
            //
            data_commentList.postValue(list)
        } else {
            //
            val list = arrayListOf<CommentContentBean>()
            comments.forEach { level1 ->
                list.add(CommentContentBean(CommentContentBean.TYPE_COMMENT_LEVEL_1, level1))
                if(level1.repliesNum > 0){
                    level1.repliesList?.forEach { level2 ->
                        list.add(CommentContentBean(CommentContentBean.TYPE_COMMENT_LEVEL_2, level2, level1))
                    }
                    val showNum = level1.repliesList?.size ?: 0
                    if(showNum >= level1.repliesNum.toInt()){
                        list.add(CommentContentBean(CommentContentBean.TYPE_COMMENT_END_TO_HIDE, level1))
                    } else {
                        list.add(CommentContentBean(CommentContentBean.TYPE_COMMENT_END_TO_VIEW_MORE, level1))
                    }
                }
            }
            list.add(CommentContentBean(CommentContentBean.TYPE_SPACE_FOR_LISTEN_NOW, null))
            data_commentList.postValue(list)
        }
    }

    fun getCommentList(){
        val onError: (error: Throwable) -> Unit = {
            it.printStackTrace()
            errorRetry = {getCommentList()}
            action_networkError.postValue(true)
            toView(ACTION_HIDE_DIALOG)
        }
        request(onError) {
            val result = Repo.http.commentList(contentId, 0, 1, mPageSize)
            if (result.isSuccess()) {
                mPageIndex = 2
                result.data?.let { data ->
                    comments = data
                    showComments()
                    action_finishRefresh.postValue(true)
                    if(data.size < mPageSize){
                        data_enableLoadMore.postValue(false)
                    } else {
                        data_enableLoadMore.postValue(true)
                    }
                }
            } else {
                Log.e(TAG, "result=" + result.msg)
                errorRetry = {getCommentList()}
                action_networkError.postValue(true)
            }
        }
    }

    fun onLoadMoreCommentList(){
        val onError: (error: Throwable) -> Unit = {
            it.printStackTrace()
            errorRetry = {onLoadMoreCommentList()}
            action_networkError.postValue(true)
            toView(ACTION_HIDE_DIALOG)
        }
        request(onError) {
            val result = Repo.http.commentList(contentId, 0, mPageIndex, mPageSize)
            if (result.isSuccess()) {
                mPageIndex++
                result.data?.let { data ->
                    comments.addAll(data)
                    showComments()
                    action_finishLoadMore.postValue(true)
                    if(data.size < mPageSize){
                        data_enableLoadMore.postValue(false)
                    }
                }
            } else {
                Log.e(TAG, "result=" + result.msg)
                errorRetry = {onLoadMoreCommentList()}
                action_networkError.postValue(true)
            }
        }
    }

    fun onReplyComment(parent: CommentRecordBean?, data: CommentRecordBean, text: String){
        toView(ACTION_SHOW_DIALOG)
        request {
            val parentId = (parent?: data).id
            val commentSave = Repo.http.commentSave(contentId, creatorId, text, data.channelName, parentId, data.userId)
            if (commentSave.isSuccess()) {
                //保存评论成功
                commentSave.data?.let { newComment ->
                    val target = parent ?: data
                    val result = Repo.http.commentList(contentId, target.id, 1, mSubCommentPageSize)
                    if (result.isSuccess()) {
                        result.data?.let { resultData ->
                            comments.forEach {
                                if(it.id == target.id){
                                    if (it.repliesList == null) {
                                        it.repliesList = arrayListOf()
                                    }
                                    it.repliesNum++
                                    it.repliesList!!.clear()
                                    it.repliesList!!.addAll(resultData)
                                }
                            }
                        }
                        //
                        showComments()
                    } else {
                        Log.e(TAG, "result=" + result.msg)
                        result.msg.let { sendHintMessage(it) }
                    }
                }
            } else {
                Log.e(TAG, "result=" + commentSave.msg)
                commentSave.msg.let { sendHintMessage(it) }
            }
            toView(ACTION_HIDE_DIALOG)
        }
    }

    fun onDeleteComment(parent: CommentRecordBean?, data: CommentRecordBean){
        toView(ACTION_SHOW_DIALOG)
        request {
            val result = Repo.http.commentRemove(data.id)
            if (result.isSuccess() && true == result.data) {
                //
                if(parent == null){
                    comments.remove(data)
                } else {
                    comments.forEach {
                        val success = it.repliesList?.remove(data) ?: false
                        if(success){
                            it.repliesNum--
                        }
                    }
                }
                showComments()

            } else {
                Log.e(TAG, "result=" + result.msg)
                result.msg.let { sendHintMessage(it) }
            }
            toView(ACTION_HIDE_DIALOG)
        }
    }

    fun onViewMoreComment(data: CommentRecordBean){
        toView(ACTION_SHOW_DIALOG)
        val onError: (error: Throwable) -> Unit = {
            it.printStackTrace()
            errorRetry = {onViewMoreComment(data)}
            action_networkError.postValue(true)
            toView(ACTION_HIDE_DIALOG)
        }
        var pageIndex: Int
        if (data.repliesList == null) {
            pageIndex = 1
        } else {
            val i = data.repliesList!!.size / mSubCommentPageSize
            pageIndex = i + 1
        }
        request(onError) {
            val result = Repo.http.commentList(contentId, data.id, pageIndex, mSubCommentPageSize)
            if (result.isSuccess()) {
                result.data?.let { resultData ->
                    //add data
                    comments.forEach {
                        if(it.id == data.id){
                            if (it.repliesList == null) {
                                it.repliesList = arrayListOf()
                            }
                            it.repliesList!!.addAll(resultData)
                        }
                    }
                    //show data
                    showComments()
                }
            } else {
                Log.e(TAG, "result=" + result.msg)
                errorRetry = {onViewMoreComment(data)}
                action_networkError.postValue(true)
            }
            toView(ACTION_HIDE_DIALOG)
        }
    }

    fun onHideComment(data: CommentRecordBean){
        comments.forEach {
            if(it.id == data.id){
                it.repliesList?.clear()
            }
        }
        showComments()
    }

    fun setNewComment(comment: CommentRecordBean){
        /*comments.add(0, comment)
        showComments()*/
        getCommentList()
    }
}